#!/usr/bin/env python

#from Bowman, Samuel. 2011. Vowel Harmony, Opacity, and Finite-State OT. MA Thesis, The University of Chicago.

import sys, os, re, string, copy
from optparse import OptionParser
sys.path[0:0] = 'src' # puts the /foo directory at the start of your path
from pyphon_generate import *
from pyphon_maketableaux import *
import pyphon_maketableaux, pyphon_generate

usage = \
"""
pyphon_recurse.py modelfile inputfile

Read a PyPhon model and a file of inputs (on separate lines) and write a list of cyclic-evaluation contenders to disk. Since this depends on ERCs, it is presently limited to OT, and will not generate HG typologies.

The model filename must have no suffix, and must refer both to a model file (.mod), as built by pyphon_makemodel.py, and to a model description file (.csv).

The input file must be a single input on a single line, with affixes separated by \. and the stem delimited by \#:, as in:

a\.b\.c\#de\#f\.g

The output will be [inputfile]-[modelfile]-recursive_typology.csv.
"""
	

			
def main(model, ifn):	
	ercs_exists = 0

	def process(output, con, words):
		'Run one tier'
		loutput = open("recurse_temp.csv",'w')
	
		wordsrem = []
	
		for word in words:
			stem = word[0]
			laffixes = word[1]
			raffixes = word[2]
			input = word[3]
			erc = word[4]
			interm = copy.deepcopy(word[5])
			interm.append(stem)
			laffixes_rem = laffixes[:]
			raffixes_rem = raffixes[:]
			
			la = ra = ''
			if laffixes_rem: 
				la = laffixes_rem.pop() 
			if raffixes_rem: 
				ra = raffixes_rem.pop() 
			if not (la + ra):
				output.write(input+', '+stem+', '+erc+', '+('>'.join(word[5]))+'\n')
				continue
			else:
	
				word[1] = laffixes_rem
				word[2] = raffixes_rem
		
				
				fstem = la + "#" + stem + "#" + ra	
				stem = la + "\#" + stem + "\#" + ra
						
				# Produce the stem input
				# print "writing", stem, infilename
				loutput.write(stem+'\n')
				word[5] = interm
				word[0] = stem
				wordsrem.append(word)
			
		loutput.close()
		
		if wordsrem==[]:
			return
		
		pyphon_maketableaux.main(model, "recurse_temp", "ot", "recurse_tab_temp")
		
		cmd = "cat recurse_tab_temp.csv"
		os.system(cmd)
		
		if not con:
			infile = open("recurse_tab_temp.csv", 'r')
			for line in infile:
				if line and line[0:3]==",,,":
					line = line.replace("\r","")
					line = line.replace("\n","")
					sectioned = line.rsplit(',')
					con = sectioned[3:]
					#print "Found con:", con
				break
			infile.close()
		
		cache = []
		
		for word in wordsrem:
			erc = word[4]
			stem = word[0]
			
			# Generate ERCs
			if erc != "0":
				ercs_exists = 1
				eoutput = open('ercs.csv','w')
				eoutput.write('\nERCS, gram\n')
				w=[]
				l=[]
				e=[]
				i=0
				ci=0
				while 1:
					#order W L E
					if i==len(erc):
						break
					if erc[i] == 'w':
						w.append(con[ci])
					elif erc[i] == 'l':
						l.append(con[ci])
					elif erc[i] == 'e':
						e.append(con[ci])
					elif erc[i] == '_':
						eoutput.write((' '.join(w)) + ", " + (' '.join(l)) + ", " + (' '.join(e)) + "\n")
						w=[]
						l=[]
						e=[]
						ci=-1
					i=i+1
					ci=ci+1
					
						
				eoutput.write((' '.join(w)) + ", " + (' '.join(l)) + ", " + (' '.join(e)) + "\n\nERCS, blank\n,,\n")
				eoutput.close()
				
				pyphon_generate.main("recurse_tab_temp.csv", "recurse_typ_temp", "ot", "ercs", "gram")
			else:
				pyphon_generate.main("recurse_tab_temp.csv", "recurse_typ_temp", "ot")
			#Here we generate a typology for all of the inputs when we only need one. It may shave runtime to limit this, but not my much.
	
			
			infile = open("recurse_typ_temp.csv", 'r')
			erc = ""
			
			
			for line in infile:
			
				#if "Input,Output," in line:
				#	sectioned = line.rsplit(',')
				#	con = sectioned[2:]
					
				if line and line[0]=="/":
					line = line.replace("\r","")
					line = line.replace("\n","")					
					n = re.search('(?<=/).+(?=/)', line)
					input = n.group(0)
					
					stem = re.sub('(\\\)','',stem)
					if input != stem:
						continue
					
					n = re.search('(?<=\{).*?(?=\})', line)
					if n:
						ercset = n.group(0)
					else:
						ercset = ""
					
					ercs=[]
		
					for n in re.finditer('[wel]+', ercset):
						if n.group(0) not in ercs:
							ercs.append(n.group(0))
					if word[4]!="0":
						ercs.append(word[4])
					
					if ercs:				
						erc = "_".join(ercs)
					else:
						erc = "0"
					
					for m in re.finditer('(?<=\[).*?(?=\])', line):
						fstem_out = re.sub('[\#\.]','',m.group(0))
						candidate = [fstem_out, word[1], word[2], word[3], erc, word[5]]
						if candidate not in cache:
							cache.append(candidate)
			infile.close()
		loutput.close()			
		process(output, con, cache)	
		#process_erc(output, con, words)

	# Read the first line of the input file. Hopefully this is the only line.
	infilename = ifn
	if ".csv" in infilename:
		infilename = infilename[:-4]
	
	infile = open(infilename + ".csv", 'r')
	print "Recurse over:"
	
	inputs = []
	
	for line in infile:
		if line[0]=="#" or len(line)==1:
			continue

		line = line.rstrip("\n")		
		print line
		
		# Separate the affixes
		sectioned = line.rsplit('\#')
		if len(sectioned)>1:
			stem = sectioned[1];
			laffixes = sectioned[0].rsplit('\.') # Affixes are ordered by distance, not orthography, so reverse the left
			raffixes = (sectioned[2].rsplit('\.'))[::-1]
		else:
			stem = sectioned[0] #robustness to inputs without morpheme boundries
			laffixes = raffixes = [] 	
		inputs.append([stem, laffixes, raffixes, line, '0', []])
	
	#print stem, laffixes, raffixes
	
	# Produce the stem input
	output = open('recurse_inp_temp.csv','w')
	for word in inputs:
		output.write('\#'+word[0]+'\#\n')
	output.close()
	
	
	output = open(model + '_' + infilename + '_recursive_typology.csv','w')
	output.write('Input, Output, ERCs, Intermediate Forms\n')
#output.write('Input, '+input+"\n")
	
	
	process(output, [], inputs)
	output.close()
	print "Wrote recursive typology to", model + '_' + infilename + '_recursive_typology.csv'
	os.remove('recurse_temp.csv')
	os.remove('recurse_inp_temp.csv')
	os.remove('recurse_tab_temp.csv')
	os.remove('recurse_typ_temp.csv')
	if ercs_exists:
		os.remove('ercs.csv')
	



if __name__ == "__main__":
    parser = OptionParser(usage=usage)
    parser.add_option('-V', '--version', action='store_true', dest='version',
            default=False,
            help='Print pyPhon version and quit.')
    p_options, args = parser.parse_args()

    if p_options.version:
        print 'pyPhon version %s.' % pyphon.__version__
        raise SystemExit

    if len(args) < 2:
        print usage
    elif len(args) < 3:
        main(args[0], args[1])
    else:
        print usage

